from visual import *
import time 
from ballGenerator import getBallPosition, getNewBall, getNewBallOnCanon
from ballFinder import getAllHits, getOneHit
from placeFinder import getPossiblePlaces, getOnePlace
from collectionFinder import checkForCollection, eraseCollection, collectionBalls, findLonelyBalls
from ballMover import moveBallsZ
from constants import numberOfLines, canonStart, defaultRadius, sphereDistance, sin60

allBalls = []
emptyPlaces = []
scene.autoscale = false;

i = 0
while i < 5:
    j = 0 
    while j < numberOfLines:
        k = 0
        while k < numberOfLines:
            rate(100)
            position = getBallPosition(i,j,k)
            if position:
                newBall = getNewBall()
                newBall.pos = position
                newBall.opacity = (1 - 0.1 * i)
                allBalls.append(newBall)
            k = k + 1
        j = j + 1
    i = i + 1
#generiraju se kugle i stavljaju u listu allBalls

while i < 9:
    j = 0
    while j < numberOfLines:
        k = 0
        while k < numberOfLines:
            position = getBallPosition(i,j,k)
            if (position and abs(j)%2==0) or (position and k!=-1):
                emptyPlaces.append(position)
            k = k + 1
        j = j + 1
    i = i + 1
#puni se lista praznih mjesta emptyPlaces

floor = box(pos=(-1 * defaultRadius , -1 * defaultRadius, -1 * defaultRadius), 
            length = (2 * numberOfLines + 1) * defaultRadius, 
            height = 2 * numberOfLines * defaultRadius, 
            width = 0.01, 
            opacity = 0.5)
#pod sa stražnje strane

canon = arrow(pos=canonStart)
#canon je strelica za gađanje

activeBall = getNewBallOnCanon()

score = 0
numberOfMisses = 0
play = 1
turnAddLayer = 1
#varijabla koja određuje poziciju novog sloja koji se dodaje odozdola
scoreLabel = label(pos=(4,4), box=1, color=color.yellow, height= 24, text=str(score))
statusLabel = label(pos=(-5,9), box=1, color=color.yellow, height= 24, text="pucaj")
while play:

    canon.axis = norm(vector(scene.mouse.ray.x * 2, scene.mouse.ray.y * 2, scene.mouse.ray[2])) * 2
    if scene.mouse.events:
        m = scene.mouse.getevent()
        if m.click:
            #nakon klika
            hitLocation = None
            hitBalls = getAllHits(allBalls, canon)
            #dobije se lista indexa kugli na putanji
            if hitBalls:                    
                minimumIndex = getOneHit(hitBalls, allBalls, canon)
                #dobije se index pogodjene kugle
                print ("konacni index pogodjene kugle je", minimumIndex)
                possiblePlaces = getPossiblePlaces (allBalls, minimumIndex, emptyPlaces)
                #traze se slobodna mjesta oko pogodjene kugle
                if possiblePlaces:
                    minimumIndexPlace = getOnePlace (possiblePlaces, emptyPlaces, canon)
                    #trazi se slobodno mjesto najblize liniji hica
                    print ("konacni index mjesta je", minimumIndexPlace)
                    hitLocation = emptyPlaces.pop(minimumIndexPlace)
                    

            #ako je proma??aj onda je lista prazna pa ide odmah na novi hitac
            print ("novi pucanj")

            
            i = 0
            while i < 80:
                #slanje kugle
                rate(60)
                
                activeBall.pos = activeBall.pos + canon.axis / 10
                #ako je kugla dalje od topa nego mjesto koje treba doci kad pogodi, zaustavi ju
                if hitLocation and (canonStart - activeBall.pos).mag >= (canonStart - hitLocation).mag:
                    i = 80
                    activeBall.pos = hitLocation
                    activeBall.opacity = (1 - 0.075 * (activeBall.pos.z / sphereDistance / sin60))
                    allBalls.append(activeBall)
                    #postavljanje kugle na slobodno mjesto
                    print ("provjera kombinacije")
                    checkForCollection(activeBall, allBalls)
                    #poziva se funkcija za provjeru mogucih kombinacija
                    print ("ima ih", len(collectionBalls), "u collectionBalls")
                    if len(collectionBalls) >= 3:
                        time.sleep(.5)
                        eraseCollection(allBalls, emptyPlaces)
                        #ako su najmanje tri istobojne kugle na hrpi brise ih se
                        findLonelyBalls(allBalls)
                        #trazi izoliranu kuglu
                        score = score + (len(collectionBalls) - 2) * 100
                        scoreLabel.text = str(score)
                    else:
                        numberOfMisses = numberOfMisses + 1
                        
                i = i + 1
                    
            if not hitLocation:
                activeBall.visible = false
                numberOfMisses = numberOfMisses + 1
                print("promasaj")
            #ako 3 promašaja zaredom
            if (numberOfMisses == 3):
                            numberOfMisses = 0
                            moveBallsZ(allBalls, emptyPlaces, turnAddLayer)
                            #ovisno o tome je li pomak paran ili neparan različita je pozicija novog reda
                            if (turnAddLayer == 1):
                                turnAddLayer = 0
                            else:
                                turnAddLayer = 1
                            for index in range(len(allBalls)):
                                if (allBalls[index].pos.z > 8.5):
                                    print("gotovo")
                                    statusLabel.text = ("kraj igre")
                                    play = 0
                                    #ako se kugle previše približe, igra gotova

                                  

            activeBall = getNewBallOnCanon()
            del collectionBalls[:]


               
